<!--设计器数据源配置表单-->

<template>
  <PnDrawer title="数据源配置"
          :width="530"
          :closable="true"
          :mask-closable="true"
          :draggable="false"
          v-model="visible"
          @on-close="cancel" @on-dom-done="domDoneHandler">
    <div class="">
      <Form :label-width="105">
        <FormItem class="m-b-5px" label="数据源类型">
          <Select v-model="ds_type">
            <Option v-for="item in dsTypesSelectDataComputed" :value="item.value" :key="item.value">{{ item.label }}</Option>
          </Select>
        </FormItem>

        <FormItemPanel title="数据结果集应为一个数组，数组元素应该包含如下字段">
          <Table size="small" :columns="tableColumns" :data="tableData"></Table>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'static'" title="静态数据结果集编辑">
          <Button class="m-b-5px" size="small" type="primary" :style="{float: 'right'}" @click="resetDefaultResultObj">恢复为组件默认静态数据</Button>
          <div class="clearfix"></div>
          <CodeEditor v-model="resultObjData" mode="json" @on-submit-change="updateResultObj"></CodeEditor>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'api'">

          <Timeline pending>
            <TimelineItem>
              <p class="time-line-item-label float-left">接口地址</p>
              <PageAllBindingVariateNamesPoptip class="float-right m-b-5px"></PageAllBindingVariateNamesPoptip>
              <div class="clearfix"></div>
              <CodeEditor v-model="apiPathData" mode="text" :height="80" placeholder="例：http://api?param=:param" @on-submit-change="updateApiPath"></CodeEditor>
              <Checkbox class="m-t-5px m-b-5px" v-model="ds_useHttpServerProxy" @on-change="invokeApiPath">服务器代理请求（因跨域无法请求时使用）</Checkbox>

              <div v-show="ds_apiMethod != null">
                <p class="m-b-5px m-t-5px">请求方式</p>
                <Select v-model="ds_apiMethod" @on-change="invokeApiPath">
                  <Option value="GET">GET</Option>
                  <Option value="POST">POST</Option>
                </Select>
              </div>

              <div v-if="ds_apiHeaders != null">
                <p class="m-b-5px m-t-5px">
                  Headers
                  <Tooltip content="此处配置的数据，将会以请求的头数据一起提交，必须为严格的JSON格式数据，键值不能带有中文字符" placement="top" max-width="200">
                    <Icon type="md-information-circle" size="15"/>
                  </Tooltip>
                </p>
                <CodeEditor v-model="apiHeadersData" mode="json" @on-submit-change="updateApiHeaders"></CodeEditor>
              </div>

              <div v-if="ds_apiMethod == 'POST' && ds_apiPostData != null">
                <p class="m-b-5px m-t-5px">POST请求参数</p>
                <CodeEditor v-model="apiPostDataData" mode="json" @on-submit-change="updateApiPostData"></CodeEditor>
              </div>

              <!--URL联动参数配置-->
              <Alert class="m-t-5px" v-if="linkageUrlParamsFormData.items.length == 0" type="info" show-icon>
                当前未配置相关URL联动参数，配置联动参数可动态将当前URL的参数信息合并至接口地址中。
              </Alert>
              <Form class="m-t-5px" :model="linkageUrlParamsFormData" :label-width="60" style="width: 300px">

                <FormItem
                    v-for="(item, index) in linkageUrlParamsFormData.items"
                    :key="item.id"
                    :label="'联动参数'"
                >
                  <i-col span="18">
                    <Input size="small" type="text" v-model="item.field" @on-blur="updateLinkageUrlParams" placeholder="必填，请输入联动参数名"/>
                  </i-col>
                  <i-col span="4" offset="1">
                    <Button size="small" type="error" @click="handleRemove(index)"><Icon type="md-trash"></Icon></Button>
                  </i-col>
                </FormItem>
                <FormItem>
                  <Row>
                    <i-col span="12">
                      <Button size="small" type="dashed" long @click="handleAdd" icon="md-add">添加联动参数</Button>
                    </i-col>
                  </Row>
                </FormItem>
              </Form>
              <!--URL联动参数配置 end-->
            </TimelineItem>
            <TimelineItem :color="invokeError?'red':'green'">
              <p class="time-line-item-label">
                响应结果集（只读）
              </p>
              <Tooltip style="text-align: justify;" v-if="ds_invokeResultClipping != undefined"
                       :content="dsResultObjClippingTooltipText" :max-width="200" placement="left">
                <Checkbox class="m-b-10px" v-model="ds_invokeResultClipping">
                  结果集裁剪，裁剪数量 <InputNumber size="small" :max="10000" :min="1" :step="1" v-model="ds_ResultClippingLimit" style="width: 60px;"></InputNumber>
                </Checkbox>
              </Tooltip>
              <Button class="m-b-10px" size="small" type="primary" :loading="refreshBtnLoading" long @click="invokeApiPath">重载</Button>
              <CodeEditor v-model="resultObjData" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>

          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'websocket'">
          <Alert show-icon type="warning" style="margin-bottom: 0px;" v-show="ds_wsPath == undefined">
            当前组件无法配置WebSocket相关信息，请尝试升级组件
          </Alert>
          <Timeline pending>
            <TimelineItem v-show="ds_wsPath != undefined">
              <p class="time-line-item-label float-left">WS地址<span class="color-red">（注：WS地址不支持使用内置交互变量）</span></p>
              <div class="clearfix"></div>
              <CodeEditor v-model="ds_wsPath" mode="text" :height="80" placeholder="例：ws://"></CodeEditor>
              <div class="m-t-5px">
                <Button size="small" type="default" :loading="testWebsocketBtnLoading"
                        v-show="wsObj.readyState == null || wsObj.readyState == 0 || wsObj.readyState == 3"
                        @click="testWebsocket">测试连接</Button>
                <Button size="small" v-show="wsObj.readyState == 1" @click="closeWebsocket">关闭连接</Button>
              </div>
            </TimelineItem>
            <TimelineItem v-show="ds_wsPath != undefined" :color="invokeError?'red':'green'">
              <p class="time-line-item-label">
                响应结果集（只读）
              </p>
              <CodeEditor v-model="resultObjData" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>
          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'database'">
          <Timeline pending>
            <TimelineItem>
              <p class="time-line-item-label">选择数据库</p>
              <Select transfer placement="bottom-end" v-model="ds_database">
                <Option v-for="item in allDatabase" :label="item.alias_name" :value="item.pool_name" :key="item.id">
                  <span>{{ item.alias_name }} - 引用名：{{item.pool_name}}</span>
                  <p style="color: #808695;">{{item.url}}</p>
                </Option>
              </Select>
            </TimelineItem>
            <TimelineItem>
              <p class="time-line-item-label float-left">SQL语句</p>
              <PageAllBindingVariateNamesPoptip class="float-right m-b-5px"></PageAllBindingVariateNamesPoptip>
              <div class="clearfix"></div>
              <CodeEditor v-model="sqlData" mode="sql" @on-submit-change="updateSql"></CodeEditor>
            </TimelineItem>
            <TimelineItem :color="invokeError?'red':'green'">
              <p class="time-line-item-label">
                响应结果集（只读）
              </p>
              <Tooltip style="text-align: justify;" v-if="ds_invokeResultClipping != undefined"
                       :content="dsResultObjClippingTooltipText" :max-width="200" placement="left">
                <Checkbox class="m-b-10px" v-model="ds_invokeResultClipping">
                  结果集裁剪，裁剪数量 <InputNumber size="small" :max="10000" :min="1" :step="1" v-model="ds_ResultClippingLimit" style="width: 60px;"></InputNumber>
                </Checkbox>
              </Tooltip>
              <Button class="m-b-10px" size="small" type="primary" :loading="refreshBtnLoading" long @click="invokeSql">重载</Button>
              <CodeEditor v-model="resultObjData" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>
          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'shareDatasource'">
          <Timeline pending>
            <TimelineItem>
              <p class="time-line-item-label">选择共享数据源</p>
              <Select style="margin-bottom: 10px; width: 354px; float: left;" filterable v-model="ds_shareDatasourceKey" @on-change="invokeShareDatasource">
                <Option v-for="(item, index) in allShareDatasourceKeys" :value="item.value" :label="item.label" :key="index">
                  <p>备注名称：{{item.label}} | 类型：{{item.dsType | dsTypeFilter}}</p>
                </Option>
              </Select>
              <Button class="m-l-5px" type="default" style="float: left;" @click="unbindShareDatasourceKey">解除绑定</Button>
              <div class="clearfix"></div>
            </TimelineItem>
            <TimelineItem>
              <p class="time-line-item-label">
                响应结果集（只读）
              </p>
              <Tooltip class="w-full"
                       content="如果当前组件使用了共享数据源，重载的数据为目标共享数据源组件最后一次返回的数据，如果找不到共享数据源结果集数据，那么重载将会恢复为当前组件默认静态数据"
                       :max-width="200" placement="left">
                <Button class="m-b-10px" size="small" type="primary" :loading="refreshBtnLoading" long @click="invokeShareDatasource">重载</Button>
              </Tooltip>
              <CodeEditor v-model="resultObjData" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>
          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-show="ds_type == 'csv'">
          <Timeline pending>
            <TimelineItem>
              <p class="time-line-item-label">选择CSV数据源</p>
              <Select style="width: 380px; margin-right: 5px;" clearable v-model="ds_csvDatasourceName" @on-change="csvDatasourceChangeHandle">
                <Option v-for="item in allCsvDatasource" :value="item.name" :key="item.id">{{ item.name }}</Option>
              </Select>
              <Button type="primary" @click="openCsvDatasourceForm">新建</Button>
            </TimelineItem>
            <TimelineItem :color="invokeError?'red':'green'">
              <p class="time-line-item-label">
                响应结果集（只读）
              </p>
              <Button class="m-b-10px" size="small" type="primary" :loading="refreshBtnLoading" long @click="invokeCsv">重载</Button>
              <CodeEditor v-model="resultObjData" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>
          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-if="ds_useFilter" title="结果集过滤">
          <Timeline pending>
            <TimelineItem>
              <p class="time-line-item-label">自定义代码过滤</p>
              <Select style="margin-bottom: 10px;" clearable @on-change="filterSelectChangeHandle" placeholder="可选项：选择预设的结果集过滤器进行代码覆盖（选中状态不保存）">
                <Option v-for="item in allFilter" :value="item.filter_code" :key="item.id">{{ item.name }}</Option>
              </Select>
              <CodeEditor v-model="filterCodeData" :placeholder="'示例：\nlet newData = [{}];\nds_resultObj = newData;'" @on-submit-change="updateFilterCode"></CodeEditor>
            </TimelineItem>
            <TimelineItem :color="invokeError?'red':'green'">
              <p class="time-line-item-label">
                过滤后结果集（只读）
              </p>
              <CodeEditor v-model="resultObjDataFromFilter" mode="json" :readOnly="true"></CodeEditor>
            </TimelineItem>
          </Timeline>
        </FormItemPanel>

        <FormItemPanel v-show="['api','database','csv'].indexOf(ds_type) > -1">
          <div slot="title">
            <span>动态加载成功回调脚本 </span>
            <Tooltip content="组件采用API、数据库、CSV作为数据源时，当数据调用成功回调时执行的脚本，此脚本只在预览或发布状态下才会运行，作用域与初始化运行脚本中相同，可通过response变量获取动态调用返回的数据" placement="top" max-width="200">
              <Icon type="md-information-circle" size="15"/>
            </Tooltip>
          </div>
          <CodeEditor v-model="ds_dynamicDatasourceSuccessCallbackCode"></CodeEditor>
        </FormItemPanel>

        <FormItemPanel v-show="ds_useTimer && ds_type != 'websocket' && ds_type != 'shareDatasource'" title="定时轮询器">
          <Alert type="info" show-icon style="padding-right: 10px;">
            定时轮询器只有在预览模式与发布模式下生效，设计器中无法看到效果。
          </Alert>
          <FormItem label="启用自动更新">
            <i-switch v-model="ds_autoRefresh">
              <span slot="open"></span>
              <span slot="close"></span>
            </i-switch>
          </FormItem>
          <FormItem label="频率">
            <InputNumber size="small" :max="10000" :min="1" v-model="ds_autoRefreshDuration"></InputNumber> 秒一次
          </FormItem>
        </FormItemPanel>

      </Form>

      <CsvDatasourceForm ref="csvDatasourceForm" @refreshDataList="addCsvDatasourceSuccessHandler"></CsvDatasourceForm>
    </div>
  </PnDrawer>
</template>

<script>

  import CsvDatasourceForm from '../../views/components/admin/csvDatasource/CsvDatasourceForm'

  import { createHelpers } from 'vuex-map-fields';

  const { mapFields } = createHelpers({
    getterType: 'designer/getLayoutItem',
    mutationType: 'designer/updateLayoutItem',
  });

  export default {
    name: 'DatasourceSettingForm',
    components: {
      CsvDatasourceForm
    },
    props: {
      show: {
        type: Boolean
      },
      targetComp: {
        type: String,
        default: ''
      },
      dsTypesSelectData: {
        type: Array,
        default () {
          return []
        }
      },
      showMappingSetting: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        visible: this.show,

        uri_project_id: this.$PnUtil.getUrlParam("project_id"), // 获取设计器URI中存储的工程ID

        invokeError: false,
        refreshBtnLoading: false,

        tableColumns: [
          {
            type: 'index',
            width: 30,
            align: 'center'
          },
          {
            title: '字段',
            width: 100,
            key: 'field'
          },
          {
            title: '备注',
            key: 'remark'
          }
        ],

        filterCodeData: '',
        resultObjData: '',
        resultObjDataFromFilter: '',
        apiPathData: '',
        apiHeadersData: '',
        apiPostDataData: '',

        linkageUrlParamsFormData: {
          items: [

          ]
        },

        wsObj: {
          readyState: null
        },
        testWebsocketBtnLoading: false,

        allDatabase: [],
        sqlData: '',

        // csv数据源
        allCsvDatasource: [],

        // shareDatasource数据源
        allShareDatasourceKeys: [],

        allFilter: [],

        dsResultObjClippingTooltipText: '当组件数据源类型为API或数据库时，可对数据源返回的原始结果集从第一个元素开始按裁剪数量进行裁剪，只有当返回的结果集格式为数组类型时才会进行裁剪操作，修改配置后点击重载查看效果'
      }
    },
    mounted() {

    },
    destroyed() {
      this.$EventBus.$off('pn_filterChange')
    },
    methods: {

      init () {
        this.filterCodeData = this.ds_filterCode;
        this.resultObjData = JSON.stringify(this.ds_resultObj, null, 2);

        this.buildResultObjFromFilter(); //初始化过滤后结果集代码编辑框

        this.apiPathData = this.ds_apiPath;
        this.apiHeadersData = JSON.stringify(this.ds_apiHeaders, null, 2);
        this.apiPostDataData = JSON.stringify(this.ds_apiPostData, null, 2);

        this.linkageUrlParamsFormData.items = this.$PnUtil.deepClone(this.ds_linkageUrlParams);

        // 初始化加载所有数据库信息
        this.$PnApi.DatabaseApi.getAllDatabase(this.uri_project_id).then(result=>{
          this.allDatabase = result.data.payload
        });
        this.sqlData = this.ds_sql;

        // 初始化加载所有csv数据源信息
        this.$PnApi.CsvDatasourceApi.getAllCsvDatasource(this.uri_project_id).then(result=>{
          this.allCsvDatasource = result.data.payload
        });

        // 初始化所有备选共享数据源
        this.allShareDatasourceKeys = [];
        let pageMetadata = this.$store.getters['designer/getPageMetadata'];
        pageMetadata.layout.layoutItems.forEach(layoutItem => {
          if (layoutItem.component.id && layoutItem.component.name == 'ShareDatasourceComp') {
            this.allShareDatasourceKeys.push({
              label: layoutItem.aliasName ? layoutItem.aliasName : layoutItem.component.id, value: layoutItem.component.id, dsType: layoutItem.component.compConfigData.ds_type
            })
          }
        })

        // 初始化加载所有过滤器数据
        this.loadAllFilter();
        this.$EventBus.$on('pn_filterChange', ()=>{
          this.loadAllFilter();
        })
      },

      resetDefaultResultObj () {
        if (this.targetComp) {
          let compConfigData = this.$PnUtil.getCompConfigData(this.targetComp);
          this.resultObjData = JSON.stringify(compConfigData.ds_resultObj, null, 2);
          this.updateResultObj()
        }else {
          this.$Message.error('找不到目标组件')
        }
      },

      updateResultObj () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_resultObj',
          value: JSON.parse(this.resultObjData)
        });
      },

      /*****************过滤器相关操作****************/
      loadAllFilter () {
        this.$PnApi.FilterApi.getAllFilter().then(result=>{
          this.allFilter = result.data.payload
        })
      },

      // 运行过滤器重新渲染结果集
      runFilterCode (data, filterCode) {
        // let ds_resultObj = this.$PnUtil.deepClone(data);
        // try{
        //   eval(filterCode);
        // }catch (e) {
        //   this.$Notice.error({
        //     title: '过滤器运行错误',
        //     desc: e.message,
        //     duration: 8
        //   })
        //   console.error(e)
        // }
        // return ds_resultObj;
        return this.$PnDesigner.dsResultObjMappingFilter(this.compConfigData, this.$PnDesigner.dsResultObjCustomCodeFilter(this.compConfigData, data))
      },

      buildResultObjFromFilter () {
        if (this.filterCodeData) {
          this.resultObjDataFromFilter = JSON.stringify(this.runFilterCode(JSON.parse(this.resultObjData), this.filterCodeData), null, 2)
        }else {
          this.resultObjDataFromFilter = ''
        }
      },

      updateFilterCode () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_filterCode',
          value: this.filterCodeData
        });
        this.buildResultObjFromFilter()
      },

      filterSelectChangeHandle (val) {
        if (this.ds_filterCode) {
          this.$Modal.confirm({
            title: '提醒',
            content: '确认使用选中的结果集过滤器进行代码覆盖吗？',
            onOk: () => {
              this.filterCodeData = val;
              this.updateFilterCode()
            }
          });
        }else {
          this.filterCodeData = val;
          this.updateFilterCode()
        }
      },
      /*****************过滤器相关操作 end ****************/

      /*****************API接口****************/
      updateApiPath () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_apiPath',
          value: this.apiPathData
        });
        this.invokeApiPath()
      },

      updateApiHeaders () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_apiHeaders',
          value: JSON.parse(this.apiHeadersData)
        });
        this.invokeApiPath()
      },

      updateApiPostData () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_apiPostData',
          value: JSON.parse(this.apiPostDataData)
        });
        this.invokeApiPath()
      },

      invokeApiPath () {
        this.refreshBtnLoading = true;
        let successHandler = (data) => {
          this.resultObjData = JSON.stringify(data, null, 2);
          this.$store.commit('designer/updateLayoutItem', {
            path: 'component.compConfigData.ds_resultObj',
            value: this.$PnDesigner.dsResultObjClipping(this.compConfigData, data)
          });
          this.invokeError = false;
          this.refreshBtnLoading = false;
        };
        let errorHandler = (error) => {
          this.invokeError = true;
          this.resultObjData = JSON.stringify(error, null, 2);
          this.refreshBtnLoading = false;
        };
        // 判断是否使用服务器代理调用
        if (this.ds_useHttpServerProxy) {
          this.$PnApi.HttpProxyApi.httpQuery(
              this.ds_apiMethod,
              this.$PnUtil.buildApiPath(this.apiPathData, this.ds_linkageUrlParams),
              this.ds_apiHeaders,
              this.ds_apiPostData).then(result => {
            successHandler(result.data)
          }).catch(error => {
            errorHandler(error)
          })
        }else {
          this.$PnApi.httpQuery(
              this.ds_apiMethod,
              this.$PnUtil.buildApiPath(this.apiPathData, this.ds_linkageUrlParams),
              this.ds_apiHeaders,
              this.ds_apiPostData).then(result => {
            successHandler(result.data)
          }).catch(error => {
            errorHandler(error)
          })
        }
      },
      /*****************API接口 end ****************/

      /*****************WebSocket****************/

      testWebsocket () {
        this.testWebsocketBtnLoading = true;
        this.wsObj = this.$WebSocketUtil.initWebSocket(this.ds_wsPath);
        if (this.wsObj.readyState == 0) {
          this.wsObj.onmessage = (result) => {
            let newResult = {data: result.data}
            if (Object.prototype.toString.call(newResult.data) === '[object String]') {
              newResult.data = JSON.parse(newResult.data)
            }
            this.resultObjData = JSON.stringify(newResult.data, null, 2);
            this.updateResultObj()
          }
          this.wsObj.addEventListener('error', ()=>{
            this.testWebsocketBtnLoading = false;
          })
        }
        if (this.wsObj.readyState == null) {
          this.testWebsocketBtnLoading = false;
        }
      },

      closeWebsocket () {
        this.testWebsocketBtnLoading = false;
        if (this.wsObj.readyState == 1) {
          this.wsObj.close();
          this.wsObj = {
            readyState: null
          };
          this.resetDefaultResultObj()
        }
      },

      /*****************WebSocket end ****************/

      /*****************URL联动参数配置相关操作****************/
      handleAdd () {
        this.linkageUrlParamsFormData.items.push({
          id: this.$PnUtil.uuid(),
          field: ''
        });
      },

      handleRemove (index) {
        if(this.linkageUrlParamsFormData.items.length > 1) {
          this.linkageUrlParamsFormData.items.splice(index, 1);
        }else {
          this.linkageUrlParamsFormData.items = []
        }
        this.updateLinkageUrlParams()
      },

      updateLinkageUrlParams () {
        let showErrorMsg = false;
        this.linkageUrlParamsFormData.items.forEach(item=>{
          if(!item.field) {
            showErrorMsg = true
          }
        });
        if (showErrorMsg) {
          this.$Message.warning({
            content: '联动参数数据存在空值项，请检查！',
            duration: 10
          })
        }else {
          this.$store.commit('designer/updateLayoutItem', {
            path: 'component.compConfigData.ds_linkageUrlParams',
            value: this.$PnUtil.deepClone(this.linkageUrlParamsFormData.items)
          });
        }
      },
      /*****************URL联动参数配置相关操作 end ****************/

      /*****************数据库数据源****************/
      updateSql () {
        this.$store.commit('designer/updateLayoutItem', {
          path: 'component.compConfigData.ds_sql',
          value: this.sqlData
        });
        this.invokeSql()
      },

      invokeSql () {
        if (this.ds_database) {
          this.refreshBtnLoading = true;
          this.$PnApi.DatabaseApi.invokeSql(this.ds_database, this.sqlData).then(result=>{
            if (result.data.success) {
              let data = this.$PnDesigner.dsResultObjClipping(this.compConfigData, result.data.payload)
              this.resultObjData = JSON.stringify(data, null, 2);
              this.$store.commit('designer/updateLayoutItem', {
                path: 'component.compConfigData.ds_resultObj',
                value: data
              });
              this.invokeError = false;
            } else {
              this.invokeError = true;
              this.resultObjData = JSON.stringify([result.data], null, 2)
            }
            this.refreshBtnLoading = false;
          }).catch(error => {
            this.invokeError = true;
            this.resultObjData = JSON.stringify(error, null, 2);
            this.refreshBtnLoading = false;
          })
        }else {
          this.$Message.warning('请选择数据库')
        }
      },
      /*****************数据库数据源 end ****************/

      /*****************共享数据源****************/

      invokeShareDatasource () {
        if (this.ds_shareDatasourceKey) {
          let data = this.$store.getters['common/getShareDatasourceResultSetItem'](this.ds_shareDatasourceKey);
          if (data) {
            this.resultObjData = JSON.stringify(data, null, 2);
            this.$store.commit('designer/updateLayoutItem', {
              path: 'component.compConfigData.ds_resultObj',
              value: data
            });
          }else {
            this.resetDefaultResultObj()
          }
        }else {
          this.resetDefaultResultObj()
        }
      },

      unbindShareDatasourceKey () {
        this.ds_shareDatasourceKey = '';
        this.resetDefaultResultObj();
        this.$Message.success('解绑成功，已恢复为默认的静态数据')
      },

      /*****************共享数据源 end ****************/

      /*****************CSV文件****************/
      csvDatasourceChangeHandle () {
        this.invokeCsv()
      },

      invokeCsv () {
        if (this.ds_csvDatasourceName) {
          this.refreshBtnLoading = true;
          this.$PnApi.CsvDatasourceApi.getCsvDatasourceByName(this.ds_csvDatasourceName).then(result=>{
            if (result.data.success) {
              this.resultObjData = result.data.payload.json_data;
              this.$store.commit('designer/updateLayoutItem', {
                path: 'component.compConfigData.ds_resultObj',
                value: JSON.parse(result.data.payload.json_data)
              });
              this.invokeError = false;
            }else {
              this.invokeError = true;
              this.resultObjData = JSON.stringify([result.data], null, 2)
            }
            this.refreshBtnLoading = false;
          });
        }else {
          this.$Message.warning('请选择CSV数据源')
        }
      },

      openCsvDatasourceForm () {
        this.$refs.csvDatasourceForm.init('add')
      },

      addCsvDatasourceSuccessHandler () {
        this.$PnApi.CsvDatasourceApi.getAllCsvDatasource(this.uri_project_id).then(result=>{
          this.allCsvDatasource = result.data.payload
        })
      },
      /*****************CSV文件 end ****************/

      cancel() {
        this.visible = false;
        this.$emit('cancel', this.visible)
        // 可以在这里编写关闭之后的逻辑处理
        this.closeWebsocket()
      },

      domDoneHandler () {
        this.$PnUtil.showMaskLayer(false)
      }

    },
    computed: {
      ...mapFields({

        id: 'component.id',
        compConfigData: 'component.compConfigData',
        text: 'component.compConfigData.text',

        ds_type: 'component.compConfigData.ds_type',
        ds_apiPath: 'component.compConfigData.ds_apiPath',
        ds_apiMethod: 'component.compConfigData.ds_apiMethod',
        ds_apiHeaders: 'component.compConfigData.ds_apiHeaders',
        ds_apiPostData: 'component.compConfigData.ds_apiPostData',
        ds_wsPath: 'component.compConfigData.ds_wsPath',
        ds_database: 'component.compConfigData.ds_database',
        ds_sql: 'component.compConfigData.ds_sql',
        ds_csvDatasourceName: 'component.compConfigData.ds_csvDatasourceName',
        ds_shareDatasourceKey: 'component.compConfigData.ds_shareDatasourceKey',
        ds_resultObjTemplate: 'component.compConfigData.ds_resultObjTemplate',
        ds_resultObj: 'component.compConfigData.ds_resultObj',

        ds_useFilter: 'component.compConfigData.ds_useFilter',
        ds_filterCode: 'component.compConfigData.ds_filterCode',
        ds_linkageUrlParams: 'component.compConfigData.ds_linkageUrlParams',

        ds_useTimer: 'component.compConfigData.ds_useTimer',
        ds_autoRefresh: 'component.compConfigData.ds_autoRefresh',
        ds_autoRefreshDuration: 'component.compConfigData.ds_autoRefreshDuration',

        ds_useHttpServerProxy: 'component.compConfigData.ds_useHttpServerProxy',

        ds_dynamicDatasourceSuccessCallbackCode: 'component.compConfigData.ds_dynamicDatasourceSuccessCallbackCode',

        ds_invokeResultClipping: 'component.compConfigData.ds_invokeResultClipping',
        ds_ResultClippingLimit: 'component.compConfigData.ds_ResultClippingLimit',

      }),

      tableData () {
        let arr = [];
        this.ds_resultObjTemplate.forEach(item=>{
          arr.push({
            field: item.field,
            remark: item.remark
          })
        });
        return arr;
      },

      dsTypesSelectDataComputed () {
        if (this.dsTypesSelectData.length > 0)
          return this.dsTypesSelectData
        else
          return this.$PnDict.dsTypes
      }
    },
    watch: {
      show(val) {
        this.visible = val
        if (val) {
          this.init()
        }
      },
      'ds_type': {
        handler: function (val) {
          if (val == 'static') {
            this.resultObjData = JSON.stringify(this.ds_resultObj, null, 2)
          }
          if (val != 'websocket') {
            this.closeWebsocket()
          }
          if (val == 'websocket' || val == 'shareDatasource') { // 当数据源类型切换为websocket或共享数据源时，将自动刷新设置为false
            this.ds_autoRefresh = false
          }
        }
      },
      'ds_resultObj': {
        handler: function () {
          this.resultObjData = JSON.stringify(this.ds_resultObj, null, 2)
          this.buildResultObjFromFilter()
        },
        deep: true
      }
    },
    filters: {
      dsTypeFilter (value) {
        switch (value) {
          case 'static':
            return '静态数据'
          case 'api':
            return 'API'
          case 'websocket':
            return 'WebSocket'
          case 'database':
            return '数据库'
          case 'shareDatasource':
            return '共享数据源'
          case 'csv':
            return 'CSV文件'
        }
      }
    }
  }
</script>

<style scoped>
  >>> .ivu-timeline-item-tail {
    border-left: 1px solid #bdbdbd !important;
  }

  .ivu-form-item {
    margin-bottom: 5px;
  }

  .time-line-item-label {
    font-size: 12px;
    font-weight: bold;
    margin-bottom: 5px;
  }

  >>> .ivu-input {
    background-color: #272822;
    color: #fff;
    border-radius: 0px;
    border: 1px solid #424242;
  }
</style>
